package com.stu.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class MotorBarView extends View {
	private Paint outlinePaint, fillPaint, grabPaint, highlightPaint;
	private int value, height, width;
	private Rect outlineRect, fillRect, grabRect;
	private boolean highlighted;
	private final static int border = 4, borderCenter = 2, grabHeight = 20, grabCenter = 10;
	private Listener valueListener;

	public interface Listener {
		public void OnValueChanged( int id, int value );
	}
	
	public MotorBarView(Context context) {
		super(context);
		init();
	}

	public MotorBarView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public MotorBarView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}
	
	public void setListener( Listener l ) {
		valueListener = l;
	}

	/**
	 * @param v Value between 0 and 100
	 */
	public void setValue( int v ) {
		value = v;
		//doCalc();
		invalidate();
	}
	
	/**
	 * @return Value between 0 and 100
	 */
	public int getValue() {
		return value;
	}
	
	private void init() {
		valueListener = null;
		value = 0;
		highlighted = false;
		outlineRect = new Rect();
		outlineRect.top = 0;
		outlineRect.left = 0;
		grabRect = new Rect();
		grabRect.left = 0;
		fillRect = new Rect();
		fillRect.left = border;

		fillPaint = new Paint();
		fillPaint.setColor(Color.BLUE);
		fillPaint.setStyle(Paint.Style.FILL);

		grabPaint = new Paint();
		grabPaint.setColor(Color.GRAY);
		grabPaint.setStyle(Paint.Style.FILL);

		highlightPaint = new Paint();
		highlightPaint.setColor(Color.GREEN);
		highlightPaint.setStyle(Paint.Style.FILL);

		outlinePaint = new Paint();
		outlinePaint.setColor(Color.BLACK);
		outlinePaint.setStrokeWidth(border);
		outlinePaint.setStyle(Paint.Style.STROKE);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		setMeasuredDimension( 40, MeasureSpec.getSize(heightMeasureSpec) );
	}

	@Override
	protected void onDraw(Canvas canvas) {
		height = getHeight();
		width = getWidth();
		int fillY = (height - grabHeight) - Math.round(((float)value / 100) * (height - grabHeight));
		fillRect.top = fillY + grabCenter;
		fillRect.right = width - border;
		fillRect.bottom = height - borderCenter;
		grabRect.top = fillY;
		grabRect.bottom = fillY + grabHeight;
		grabRect.right = width;
		outlineRect.right = width;
		outlineRect.bottom = height;
		canvas.drawRect(outlineRect, outlinePaint);
		canvas.drawRect(fillRect, fillPaint);
		if( highlighted )
			canvas.drawRect(grabRect, highlightPaint);
		else
			canvas.drawRect(grabRect, grabPaint);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if( !isEnabled() )
			return true;

		int action = event.getAction();
		if( action == MotionEvent.ACTION_UP ) {
			highlighted = false;
			invalidate();
		} else if( action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE ) {
			highlighted = true;
			float y = event.getY();
			if( y <= grabCenter ) {
				grabRect.top = borderCenter;
				grabRect.bottom = grabRect.top + grabHeight;
				fillRect.top = borderCenter;
				value = 100;
				if( valueListener != null )
					valueListener.OnValueChanged( getId(), value );
				invalidate();
			} else if( y >= (height - grabCenter) ) {
				grabRect.bottom = height;
				grabRect.top = grabRect.bottom - grabHeight;
				fillRect.top = height - grabHeight;
				value = 0;
				if( valueListener != null )
					valueListener.OnValueChanged( getId(), value );
				invalidate();
			} else {
				grabRect.bottom = (int)y + grabCenter;
				grabRect.top = grabRect.bottom - grabHeight;
				value = Math.round( ((height - y) / height) * 100 );
				fillRect.top = (int)y - borderCenter;
				if( valueListener != null )
					valueListener.OnValueChanged( getId(), value );
				invalidate();
			}
		}
		return true;
	}
}
